package com.jl.commons.shiro;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.jl.commons.constant.Constants;
import com.jl.commons.constant.ErrorMessage;
import com.jl.model.User;
import com.jl.service.IRoleService;
import com.jl.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component
public class ShiroRealm extends AuthorizingRealm {
	
	@SuppressWarnings("serial")
	public static final List<String> AUTHORIZ_SOVEREIGN_ACCOUNT = new ArrayList<String>(){{add("manager");}}; 

	@Autowired
	private IUserService userService;

	@Autowired
	private IRoleService roleService;

	@Override 
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
        String account = token.getUsername();  
        if(StringUtils.isNotEmpty(account)){
			User user = userService.selectUserByAccount(account);
			// 账号不存在
			if (user == null ) {
				return null;
			}
			// 读取用户的url(权限)和角色
			Map<String, Object> resourceMap = roleService.selectResourceMapByUserId(user.getId());
			Set<String> urls = (Set<String>) resourceMap.get("urls");
			Set<String> roles = (Set<String>) resourceMap.get("roles");
			List<Long> roleIds = (List<Long>) resourceMap.get("roleIds");
			if (roles == null || roles.isEmpty() || roles.size() < 1) {
				throw new DisabledAccountException(ErrorMessage.CURR_USER_NO_ROLE);
			}
			if (urls == null || urls.isEmpty() || urls.size() < 1) {
				throw new DisabledAccountException(ErrorMessage.CURR_USER_NO_MENU);
			}
			ShiroUser shiroUser=new ShiroUser(user.getId(), user.getUsername(),user.getLoginName(), urls);
			shiroUser.setOrganizationId(user.getOrganizationId());
			shiroUser.setRoles(roles);
			shiroUser.setRoleIds(roleIds);
			SecurityUtils.getSubject().getSession().setAttribute(Constants.CURRENT_USER,shiroUser);
            return new SimpleAuthenticationInfo(user.getLoginName(),user.getPassword(),getName());
        }  
        return null;  
	}


	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getSession().getAttribute(Constants.CURRENT_USER);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addRole("default");
		// 设置权限串
		if(AUTHORIZ_SOVEREIGN_ACCOUNT.contains(shiroUser.getUsername())){
			info.addStringPermission("*:*");
		}else{
			if(shiroUser==null || shiroUser.getRoles()==null || shiroUser.getRoles().isEmpty()){
				return null;	
			}
			info.setRoles(shiroUser.getRoles());
			info.addStringPermissions(shiroUser.getUrlSet());
		}
		return info;
	}

	@Override
	public void onLogout(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
		String userAccount = (String) principals.getPrimaryPrincipal();
		removeUserCache(userAccount);
	}

	/**
	 * 清除用户缓存
	 * @param shiroUser
	 */
	public void removeUserCache(ShiroUser shiroUser) {
		removeUserCache(shiroUser.getLoginName());
	}

	/**
	 * 清除用户缓存
	 * @param loginName
	 */
	public void removeUserCache(String loginName) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection();
		principals.add(loginName, super.getName());
		super.clearCachedAuthenticationInfo(principals);
	}


}
